package com.logbug.functional;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Flow;
import java.util.function.*;
import java.util.stream.Stream;

public class TestFunctional {
    public static void main(String[] args) {
        System.out.println("===test Consumer===");
        Consumer<String> consumer = item -> System.out.println("item = " + item);
        consumer = consumer.andThen(item -> System.out.println("after: " + item));
        Stream.of("a", "b", "c").forEach(consumer);

        System.out.println("===test Supplier===");
        Supplier<String> supplier = () -> "hello world!";
        ThreadLocal<String> threadLocal = ThreadLocal.withInitial(supplier);
        String threadLocalValue = threadLocal.get();
        System.out.println("threadLocalValue = " + threadLocalValue);

        System.out.println("===test Predicate===");
        Predicate<String> filter1 = item -> item.contains("v");
        Predicate<String> filter2 = item -> item.length() > 3;
        List<String> langList = Arrays.asList("java", "groovy", "python", "C++");
        System.out.println("result of and filter");
        langList.stream().filter(filter1.and(filter2)).forEach(item -> System.out.println("filtered item = " + item));
        System.out.println("result of or filter");
        langList.stream().filter(filter1.or(filter2)).forEach(item -> System.out.println("filtered item = " + item));

        System.out.println("===test Function===");
        Function<String, ?> func = item -> item + " language";
        langList.stream().map(func).forEach(System.out::println);
        System.out.println(langList.stream().reduce("reduced text:", (prevItem, item) -> prevItem + "," + item));
        Optional<String> minLang = langList.stream().reduce(BinaryOperator.minBy(Comparator.comparingInt(String::length)));
        System.out.println("minLang = " + minLang);

        System.out.println("===test Function reference===");
        Function<String, Integer> stringIntegerFunction = String::length;
        Integer length = stringIntegerFunction.apply("abcdefghijklmn");
        System.out.println("length = " + length);
        Function<Integer, String> publisher = String::valueOf;
        String str = publisher.apply(10001);
        System.out.println("str = " + str);
        BiFunction<String, CharSequence, Boolean> contains = String::contains;
        Boolean containsMN = contains.apply("abcdefghijklmn", "mn");
        System.out.println("containsMN = " + containsMN);



    }
}
